/********************************************************************************************
@descr This file contains helper predicates for ...
@autor Christian Arias
@date  10 june 2011
********************************************************************************************/


/********************************************************************************************
@descr Return the element at X,Y position on matrix M 
@form  getXY(Matrix,Xcoordinate,Ycoordinate,Element)
********************************************************************************************/
getXY0(M,X,Y,E):-nth0(X,M,W),nth0(Y,W,E).

/********************************************************************************************
@descr Return if the element is between LowLimit and HighLimit 
@form  in_range(Element,LowLimit,HighLimit)
********************************************************************************************/
in_range( K, K, High )  :-
   K =< High.
in_range( K, Low, High )  :-
   Low < High,
   Low1 is Low + 1,
   in_range( K, Low1, High ).
   
/********************************************************************************************
@descr Return if the element is between the limits of a board chess style (8 x 8) 
@form  ch_range(Element)
********************************************************************************************/
%ch_range(E):-in_range(E,0,7).
ch_range(0).
ch_range(1).
ch_range(2).
ch_range(3).
ch_range(4).
ch_range(5).
ch_range(6).
ch_range(7).
%short castling range and long castling range
%sc_range(E):-in_range(E,4,6).
%lc_range(E):-in_range(E,2,4).
sc_range(4).
sc_range(5).
sc_range(6).
lc_range(2).
lc_range(3).
lc_range(4).
%short castling range and long castling range
%sc_emptyRange(E):-in_range(E,5,6).
%lc_emptyRange(E):-in_range(E,1,3).
sc_emptyRange(5).
sc_emptyRange(6).
lc_emptyRange(1).
lc_emptyRange(2).
lc_emptyRange(3).
%remplazar elemento en vector
/********************************************************************************************
@descr Replace element on positon Position at list List by element E and deliver it on NList 
@form  rpM(LIST,Element,Position,NList).
********************************************************************************************/
rpM([_|T],E,0,[E|T]):-!.
rpM([H|T],E,P,[H|F]):-P2 is P-1, rpM(T,E,P2,F).

/********************************************************************************************
@descr Replace element on positon File,Column at list List by element E and deliver it on NList 
@form  rpMxT(LIST,Element,Position,NList).
********************************************************************************************/
rpMxT(Ti,InX,InY,El,Tf):-nth0(InX,Ti,FilIn),rpM(FilIn,El,InY,FilN),rpM(Ti,FilN,InX,Tf).   
   
exchange(SM,SX,SY,TX,TY,TM):-getXY0(SM,SX,SY,E),getXY0(SM,TX,TY,E2),rpMxT(SM,TX,TY,E,TT),rpMxT(TT,SX,SY,E2,TM).

find(E,[E|_],0):-!.
find(E,[_|X],P):-find(E,X,Aux),P is Aux + 1.

replace(E1,E2,L1,L2):-find(E1,L1,P),rpM(L1,E2,P,L2).

baseLine(black,7).
baseLine(white,0).
big(X,Y):-X > Y.
%isFreeRange(T):-findall(C,sc_emptyRange(C),X),maplist(big(T),X).


copiarN([E|_],1,[E]).
copiarN([H|T],P,[H|G]):-P2 is P-1,copiarN(T,P2,G).

sublista(L,1,L).
sublista([_|L],P,LF):-P2 is P-1,sublista(L,P2,LF).

replace2(L,P,E,LF):-Prev is P-1, Sig is P+1, copiarN(L,Prev,L1),agregarF(L1,E,L2),sublista(L,Sig,L3),concat(L2,L3,LF).


%contar elemento en lista
conEl([H|T],Ele,N):- H = Ele, conEl(T,Ele,N2), N is N2 + 1.
conEl([H|T],Ele,N2):- H\=Ele, conEl(T,Ele,N2).
conEl([],_,0).

%contar elemento en matriz
conElMat([H|T],X,N):-conEl(H,X,N2),conElMat(T,X,N3), N is N2 + N3.
conElMat([],_,0).
